<?php

namespace Hilaoyu\LaravelExtend\Services\AccessControl;


use Hilaoyu\LaravelExtend\Services\Auth\Traits\ModelWithLoginRefreshTrait;
use Hilaoyu\Utils\UtilSupport;
use Hilaoyu\LaravelExtend\Model;
use Illuminate\Support\Facades\Cache;

abstract class AbstractModelAccessControlRoles extends Model
{

    protected $table = 'access_control_roles';
    protected $keyType = 'char';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'id' ,
        'name' ,
        'status' ,
        'required' ,
    ];

    protected $appends = [
        'status_name',
    ];

    public function getValidationRules()
    {
        $rules = [
            'id' => 'required|string|max:36|unique:' . static::getTableCon() . ',id,'. $this->getOriginalKey() . ',' . static::getPkName() ,
            'name' => 'required|string|max:200' ,
        ];

        return $rules;
    }

    public function getStatusNameAttribute()
    {
        return 1 == $this->getAttribute('status') ? "启用" : "禁用" ;
    }

    abstract static protected function classNameModelAccessControlEntitiesRelation();

    public function accesses(){
        $class_name_model_access_control_entities_relation = static::classNameModelAccessControlEntitiesRelation();
        if(! $class_name_model_access_control_entities_relation){
            return $this->hasOne(
                get_class($this),
                $this->getKeyName()
            )->whereRaw('1=0');
        }
        return $this->hasMany(
            $class_name_model_access_control_entities_relation,
            'role_id',
            'id'
        );
    }
    public function clearOwnedAccessesCache(){
        if($_this_key = $this->getKey()){

            return Cache::forget('access_control_role_owned_accesses_'.config('app.env','').'_'.$_this_key);
        }

        return false;
    }
    public function ownedAccesses($entity_id='',$action='',$default=null){

        $entity_id = trim($entity_id);
        $action = trim($action);


        $accesses = [];
        $class_name_model_access_control_entities_relation = static::classNameModelAccessControlEntitiesRelation();

        if($this->exists && ($_this_key = $this->getKey() ) && $class_name_model_access_control_entities_relation){

            $accesses = Cache::rememberForever('access_control_role_owned_accesses_'.config('app.env','').'_'.$_this_key,function () use ($class_name_model_access_control_entities_relation,$_this_key){
                $model = UtilSupport::makeClass($class_name_model_access_control_entities_relation);
                return $model->where('role_id','=',$_this_key)->get()

                    ->groupBy('entity_id')
                    ->filter(function ($item,$entity_id) use ($class_name_model_access_control_entities_relation){
                        return UtilSupport::makeClassSingle($class_name_model_access_control_entities_relation)::getAccessControlEntities($entity_id);
                    })


                    ->map(function ($entity_group){
                        return collect($entity_group)->pluck('val','action');
                    })
                    ;
            });
        }

        if($entity_id){
            $access_key = $entity_id;
            if($action){
                $access_key .= '.' .$action;
            }

            return data_get($accesses,$access_key,$default);
        }

        return $accesses;


    }
    public function saveAccesses($accesses=[]){
        $class_name_model_access_control_entities_relation = static::classNameModelAccessControlEntitiesRelation();
        if(! $class_name_model_access_control_entities_relation){
            return false;
        }
        try{
            $this->accesses()->delete();
            $relationModels = [];

            collect($accesses)->each(function ($actions,$entity_id) use (&$relationModels,$class_name_model_access_control_entities_relation){
                if(!(UtilSupport::makeClassSingle($class_name_model_access_control_entities_relation)::getAccessControlEntities($entity_id) )){
                    return true;
                }
                collect($actions)->each(function ($val,$action)use (&$relationModels,$class_name_model_access_control_entities_relation,$entity_id){
                    if(0 == $val){
                        return true;
                    }
                    $relationModels[] = UtilSupport::makeClass($class_name_model_access_control_entities_relation,[
                        'entity_id' => $entity_id,
                        'action' => $action,
                        'val' => $val,
                    ]);
                });

            });


            //dd($accesses,$relationModels);
            if(!empty($relationModels)){
                return $this->accesses()->saveMany($relationModels);
            }

            return true;

        }catch (\Exception $exception){
            $this->setError($exception->getMessage());
        }
        return false;
    }

}
